package main

import (
	"crypto/hmac"
	"crypto/sha1"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
	"time"
)

const Type_StaticMethod = 0 // 调用静态方法
const Type_NewClass = 1     // 返回 new class 的 obj
const Type_ObjMethod = 2    // 调用 obj 的方法
const Type_ApisMethod = 3   // 调用Apis的方法

// WitSdk 参数
const witUid = ""
const witPid = ""
const witSecretId = ""
const witSecretKey = ""

// 提交的请求参数
type request struct {
	WitUid      string     `json:"witUid"`
	WitPid      string     `json:"witPid"`
	WitPluginId string     `json:"witPluginId"`
	Class       string     `json:"class"`
	Func        string     `json:"func"`
	Param       [][]string `json:"param"`
	Type        int        `json:"type"`
	Method      string     `json:"method"`
	T           int        `json:"t"`
	Sign        string     `json:"sign,omitempty"`
}

type response struct {
	ErrCode int    `json:"errCode"`
	Message string `json:"message"`
	Data    struct {
		Obj    string `json:"obj,omitempty`
		Return string `json:"return,omitempty`
	} `json:"data,omitempty"`
}

func main() {
	// 封装请求内容：先返回类数据
	req := request{
		WitUid:      witUid,
		WitPid:      witPid,
		WitPluginId: "",
		Class:       "Lib\\Api",
		Func:        "WorkWx_Test",
		Type:        Type_NewClass,
		Method:      "json",
	}
	rsp := reqApi(req)

	// 再次封装请求内容：再根据返回的类数据请求具体的方法
	req = request{
		WitUid:      witUid,
		WitPid:      witPid,
		WitPluginId: "",
		Class:       rsp.Data.Obj,
		Func:        "Test",
		Type:        Type_ObjMethod,
		Method:      "json",
	}
	rsp = reqApi(req)
	fmt.Println(rsp.Data.Return)
}

func reqApi(req request) response {
	req.Param = append(req.Param, []string{})
	req.T = int(time.Now().Unix())
	signStr, _ := json.Marshal(&req)
	req.Sign = getSign(signStr)
	reqBody, _ := json.Marshal(&req)
	r, err := http.Post("https://api.witframe.com/lib", "", strings.NewReader(string(reqBody)))
	if err != nil {
		panic(err)
	}

	// 获取回包内容
	defer r.Body.Close()
	rspBody, err := ioutil.ReadAll(r.Body)
	if err != nil {
		panic(err)
	}

	rsp := &response{}
	err = json.Unmarshal(rspBody, rsp)
	if err != nil {
		panic(err)
	}
	return *rsp
}

// getSign 计算签名
func getSign(s []byte) string {
	signStr := witSecretId + "|" + string(s)
	m := hmac.New(sha1.New, []byte(witSecretKey))
	m.Write([]byte(signStr))
	return hex.EncodeToString(m.Sum(nil))
}
